package priv.demos.demo1.solution.main;

import com.alibaba.fastjson.JSON;
import com.payment.lc.pcs.common.util.CommonUtil;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Created on 2017/1/11.
 */
public class Main3 {

    public static void main(String[] args) {

        Double.parseDouble("");

    }

    private static void test2() {
        boolean a = CommonUtil.in("a");
        System.out.println("a = " + a);

        String key = "tableHad";
        Table.TableHead value = new Table.TableHead();
        String methodName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1);
        int n = 1000;

        try {
            Method setTableHead = Table.class.getMethod(methodName, value.getClass());
            System.out.println("setTableHead = " + setTableHead);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

//        System.out.println(JSON.toJSONString(getMethods(Table.class)));
        long l1 = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            test2(value, methodName);
        }
        long l2 = System.currentTimeMillis();

        long l3 = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            test3(value, methodName);
        }
        long l4 = System.currentTimeMillis();
        System.out.println(l2 - l1);
        System.out.println(l4 - l3);
    }

    private static void test2(Object value, String methodName) {
        Method method = null;
        try {
            method = getMethod(Main3.Table.class, getMethods(Main3.Table.class), methodName, value.getClass());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    private static void test3(Object value, String methodName) {
        Method method = null;
        try {
            method = Table.class.getMethod(methodName, value.getClass());
        } catch (NoSuchMethodException e) {
//            e.printStackTrace();
        }
    }

    public static Method getMethod(Class<?> clazz, Method[] methods, String methodName,
                                   Class<?>... parameterTypes) throws NoSuchMethodException {
        if (methods == null) {
            return null;
        }
        boolean exist = false;
        Method result = null;
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                exist = true;
                break;
            }
        }
        if (exist) {
            try {
                result = clazz.getMethod(methodName, parameterTypes);
            } catch (NoSuchMethodException e) {
                throw e;
            }
        }
        return result;
    }

    public static Method getMethod(Class<?> clazz, Set<String> methods, String methodName,
                                   Class<?>... parameterTypes) throws NoSuchMethodException {
        if (methods == null) {
            return null;
        }
        boolean exist = false;
        Method result = null;
        if (methods != null && methods.contains(methodName)) {
            try {
                result = clazz.getMethod(methodName, parameterTypes);
            } catch (NoSuchMethodException e) {
                throw e;
            }
        }
        return result;
    }

    public static Method[] getMethods(Class<?> clazz) {
        return clazz.getMethods();
    }

    private static void test1() {
        Main3.Table table = new Main3.Table();
        Main3.Table.TableHead th = new Main3.Table.TableHead();
        Main3.Table.TableData td = new Main3.Table.TableData();
        th.setTh1("持有时间");
        th.setTh2("费率");
        ArrayList<Table.TableData> tds = new ArrayList<>();
        td.setTd1("111<222");
        td.setTd2("3333");
        tds.add(td);
        table.setTableHead(th);
        table.setTds(tds);

        String s = getXmlString(table);
        System.out.println("s = " + s);
        System.out.println(JSON.toJSONString(table));
        try {
            JAXBContext context = JAXBContext.newInstance(Table.class, Table.TableHead.class, Table.TableData.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            Object t = unmarshaller.unmarshal(new ByteArrayInputStream(s.getBytes()));
            System.out.println(t.getClass());
            System.out.println(JSON.toJSONString(t));
        } catch (Exception e) {

        }

    }

    private static String getXmlString(Main3.Table table) {
        String s = getXmlString(table,
                new Class[]{Main3.Table.class, Main3.Table.TableHead.class, Main3.Table.TableData.class});
        return s;
    }

    private static String getXmlString(Main3.Table table, Class[] classes) {
        String s = null;
        try {
            JAXBContext context = JAXBContext.newInstance(classes);
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            marshaller.marshal(table, outputStream);
            outputStream.close();
            s = outputStream.toString();
        } catch (Exception e) {

        }
        return s;
    }

    @XmlRootElement
    static class Table {

        private TableHead tableHead;
        private List<TableData> tds;

        public TableHead getTableHead() {
            return tableHead;
        }

        public List<TableData> getTds() {
            return tds;
        }

        @XmlElement(name = "tr")
        public void setTableHead(TableHead tableHead) {
            this.tableHead = tableHead;
        }

        @XmlElement(name = "tr")
        public void setTds(List<TableData> tds) {
            this.tds = tds;
        }

        static class TableHead {
            private String th1;
            private String th2;

            public void setTh1(String th1) {
                this.th1 = th1;
            }

            public void setTh2(String th2) {
                this.th2 = th2;
            }

            @XmlElement(name = "tableHead")
            public String[] getTh() {
                String[] ths = new String[2];
                ths[0] = th1;
                ths[1] = th2;
                return ths;
            }
        }

        static class TableData {
            private String td1;
            private String td2;

            public String getTd1() {
                return td1;
            }

            @XmlElement(name = "td")
            public void setTd1(String td1) {
                this.td1 = td1;
            }

            public String getTd2() {
                return td2;
            }

            @XmlElement(name = "td")
            public void setTd2(String td2) {
                this.td2 = td2;
            }
        }
    }
}